package br.com.statizo.financeiro.repository.impl;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import javax.persistence.Query;

import br.com.snoghert.persistence.repository.impl.SAbstractRepository;
import br.com.statizo.financeiro.entity.GrupoLancamento;
import br.com.statizo.financeiro.entity.Lancamento;
import br.com.statizo.financeiro.exception.LancamentoComParcelasException;
import br.com.statizo.financeiro.exception.NegocioException;
import br.com.statizo.financeiro.repository.RepositorioLancamento;

public class RepositorioLancamentoImpl extends SAbstractRepository<Lancamento> implements RepositorioLancamento{

	private static final long serialVersionUID = 1L;

	public RepositorioLancamentoImpl() throws ClassNotFoundException {
		super();
	}


	@Override
	public List<Integer> getYears() {

		String queryText = "select distinct(year(dataPagamento)) from Lancamento";
		Query query = entityManager.createQuery(queryText);
		try{
			return query.getResultList();
		}catch(Exception e){
			return Collections.emptyList();
		}

	}

	
	@Override
	public int getMaxYear() {

		String queryText = "select max(year(dataPagamento)) from Lancamento";
		Query query = entityManager.createQuery(queryText);
		try{
			return (int) query.getSingleResult();
		}catch(Exception e){
			return 0;
		}

	}

	public double getValorReceitas(int mes, int ano){

		String queryText = "select sum(valor) from Lancamento where month(dataPagamento) = :mes and year(dataPagamento) = :ano and controleGastos = :controle " +
				"and tipo.grupo = :grupoR";
		Query query = entityManager.createQuery(queryText);
		query.setParameter("mes", mes);
		query.setParameter("ano", ano);
		query.setParameter("controle", false);
		query.setParameter("grupoR", GrupoLancamento.RECEITA);

		try{
			return (double) query.getSingleResult();
		}catch(Exception e){
			return 0;
		}

	}


	public double getValorDespesas(int mes, int ano){

		String queryText = "select sum(valor) from Lancamento where month(dataPagamento) = :mes and year(dataPagamento) = :ano and controleGastos = :controle " +
				"and tipo.grupo != :grupoR and tipo.grupo != :grupoI";
		Query query = entityManager.createQuery(queryText);
		query.setParameter("mes", mes);
		query.setParameter("ano", ano);
		query.setParameter("controle", false);
		query.setParameter("grupoR", GrupoLancamento.RECEITA);
		query.setParameter("grupoI", GrupoLancamento.INVESTIMENTO);

		try{
			return (double) query.getSingleResult();
		}catch(Exception e){
			return 0;
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> getRecursos(int mes, int ano) {

		String queryText = "from Lancamento where month(dataPagamento) = :mes and year(dataPagamento) = :ano and recursoAlocado = :recAloc order by complemento";

		Query query = entityManager.createQuery(queryText);
		query.setParameter("mes", mes);
		query.setParameter("ano", ano);
		query.setParameter("recAloc", true);

		try{
			return query.getResultList();
		}catch(Exception e){
			return Collections.emptyList();
		}		


	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> getRecursos() {

		Query query = entityManager.createQuery("from Lancamento where recursoAlocado = :recAloc order by tipo.descricao");
		query.setParameter("recAloc", true);
		try{
			return query.getResultList();
		}catch(Exception e){
			return Collections.emptyList();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> getList(int mes, int ano, String orderBy) {

		String queryText = "from Lancamento where month(dataPagamento) = :mes and year(dataPagamento) = :ano ";

		if(orderBy != null)
			queryText+=" order by "+orderBy;

		Query query = entityManager.createQuery(queryText);
		query.setParameter("mes", mes);
		query.setParameter("ano", ano);

		try{
			return query.getResultList();
		}catch(Exception e){
			return Collections.emptyList();
		}		

	}


	@Override
	public int remove(Serializable id)  {
		try{
			return super.remove(id);	
		}catch(javax.persistence.EntityExistsException e){
			throw new LancamentoComParcelasException("Este lançamento possui parcelas vinculadas e não pode ser excluído!");
		}catch(Exception e){
			throw new NegocioException("Ocorreu um erro inesperado");
		}

	}

	@Override
	public List<Lancamento> getLancamentosDoPeriodo(int mes, int ano) {
		return getList(mes,ano,null);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> getControles(Lancamento lancamento) {

		Query query = entityManager.createQuery("from Lancamento where recurso.id = :id");
		query.setParameter("id", (Long)lancamento.getId());
		try{
			return query.getResultList();
		}catch(Exception e){
			return Collections.emptyList();
		}

	}


}